home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Mac OS SDK / Dev.CD Jan 98 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Samples / SampleCode / Plug-in - WireFrame Renderer / SR.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-14  |  26.9 KB  |  1,130 lines  |  [TEXT/MPS ]

  1. /******************************************************************************
  2.  **                                                                             **
  3.  **     Module:        SR.c                                                     **
  4.  **                                                                          **
  5.  **                                                                          **
  6.  **     Purpose:     Generic sample renderer routines                          **
  7.  **                                                                          **
  8.  **                                                                          **
  9.  **                                                                          **
  10.  **     Copyright (C) 1996 Apple Computer, Inc.  All rights reserved.          **
  11.  **                                                                          **
  12.  **                                                                          **
  13.  *****************************************************************************/
  14.   
  15. #include <assert.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18.  
  19. #include "QD3D.h"
  20. #include "QD3DErrors.h"
  21. #include "QD3DView.h"
  22. #include "QD3DDrawContext.h"
  23. #include "QD3DRenderer.h"
  24. #include "QD3DExtension.h"
  25. #include "QD3DIO.h"
  26.  
  27. #include "SR.h"
  28. #include "SR_Rasterizers.h"
  29. #include "SR_ConfigData.h"
  30.  
  31. #if defined(WINDOW_SYSTEM_MACINTOSH) && WINDOW_SYSTEM_MACINTOSH
  32.  
  33. #include <Resources.h>
  34. #include <Aliases.h>
  35.  
  36. #include "SR_MacDialog.h"
  37.  
  38. #elif defined(WINDOW_SYSTEM_WIN32) && WINDOW_SYSTEM_WIN32
  39.  
  40. #include "SR_WinDialog.h"
  41.  
  42. #endif  /*  WINDOW_SYSTEM_MACINTOSH  */
  43.  
  44.  
  45. /******************************************************************************
  46.  **                                                                             **
  47.  **                            Forward Declarations                             **
  48.  **                                                                             **
  49.  *****************************************************************************/
  50.  
  51. #if defined(WINDOW_SYSTEM_MACINTOSH) && WINDOW_SYSTEM_MACINTOSH
  52.  
  53. /*
  54.  *  Shared library initialization entry point
  55.  */
  56. OSErr SR_Initialize( 
  57.     const CFragInitBlock    *initBlock);
  58.  
  59. #elif defined(WINDOW_SYSTEM_WIN32) && WINDOW_SYSTEM_WIN32
  60.  
  61.  
  62. #endif  /*  WINDOW_SYSTEM_MACINTOSH  */
  63.  
  64. /*
  65.  *  Shared library exit function
  66.  */
  67. TQ3Status SR_Exit( 
  68.     void);
  69.  
  70. /*
  71.  *  IO Functions
  72.  */
  73. static TQ3RendererObject SR_Read(
  74.     TQ3FileObject        file);
  75.     
  76. static TQ3Status SR_Traverse(
  77.     TQ3RendererObject    renderer,
  78.     void                *unused,
  79.     TQ3ViewObject        view);
  80.  
  81. #if defined(WINDOW_SYSTEM_MACINTOSH) && WINDOW_SYSTEM_MACINTOSH
  82.  
  83. /*
  84.  * Macintosh resource fork functions
  85.  */
  86. static OSErr SR_CreateAliasHandle( 
  87.     const CFragInitBlock    *initBlock);
  88.     
  89. static TQ3Status SR_FreeAliasHandle(
  90.     void);
  91.  
  92. #endif  /*  WINDOW_SYSTEM_MACINTOSH  */
  93.  
  94. /******************************************************************************
  95.  **                                                                             **
  96.  **                                    Globals                                     **
  97.  **                                                                             **
  98.  *****************************************************************************/
  99.  
  100. static TQ3XObjectClass    SRgRendererClass;
  101. static TQ3ObjectType    SRgClassType;
  102. static unsigned long     SRgSharedLibrary = NULL;
  103.  
  104. #if defined(WINDOW_SYSTEM_MACINTOSH) && WINDOW_SYSTEM_MACINTOSH
  105.  
  106. AliasHandle SRgAliasHandle = NULL;
  107.  
  108. #endif  /*  WINDOW_SYSTEM_MACINTOSH  */
  109.  
  110.  
  111. /******************************************************************************
  112.  **                                                                             **
  113.  **                            Sample Renderer routines                         **
  114.  **                                                                             **
  115.  *****************************************************************************/
  116.  
  117. /*===========================================================================*\
  118.  *
  119.  *    Routine:    SR_IdleProgress()
  120.  *
  121.  *    Comments:    Every n primitives, call the view's idle progress method.
  122.  *
  123. \*===========================================================================*/
  124.  
  125. TQ3Status SR_IdleProgress(
  126.     TQ3ViewObject    view,
  127.     TSRPrivate        *srPrivate)
  128. {
  129.     srPrivate->primitiveCount++;
  130.     
  131.     if (srPrivate->primitiveCount % 10000 == 0) {
  132.         return (Q3XView_IdleProgress(view, 0, 0));
  133.     } else {
  134.         return (kQ3Success);
  135.     }
  136. }
  137.  
  138.  
  139. /*===========================================================================*\
  140.  *
  141.  *    Routine:    SR_UpdateRasterFunctions()
  142.  *
  143.  *    Comments:    Depending on pixel type, assign rasterization routines for
  144.  *                the cases of clipped and not clipped (windows). In the
  145.  *                case of unsupported pixel types, set rasterizers to NULL
  146.  *                NULL functions.
  147.  *
  148. \*===========================================================================*/
  149.  
  150. TQ3Status SR_UpdateRasterFunctions(
  151.     TSRPrivate        *srPrivate)
  152. {
  153.     TQ3XClipMaskState            clipMaskState;
  154.     TQ3XDrawRegionDescriptor    *descriptor;
  155.     
  156.     assert(srPrivate != NULL);
  157.  
  158.     descriptor = srPrivate->descriptor;
  159.     
  160.     switch (descriptor->pixelType) {
  161.         case kQ3XDevicePixelTypeARGB32    :
  162.         case kQ3XDevicePixelTypeRGB32    : {
  163.             srPrivate->rasterFunctions[SRcRasterBasic].lineFunction         = 
  164.                 SRLine_Rasterize_32;
  165.             srPrivate->rasterFunctions[SRcRasterBasic].pointFunction         = 
  166.                 SRPoint_Rasterize_32;
  167.             srPrivate->rasterFunctions[SRcRasterBasic].markerFunction         = 
  168.                 SRMarker_Rasterize_32;
  169.             srPrivate->rasterFunctions[SRcRasterBasic].pixmapMarkerFunction    = 
  170.                 SRPixmapMarker_Rasterize_32;
  171.  
  172.             srPrivate->rasterFunctions[SRcRasterClip].lineFunction             = 
  173.                 SRLine_Rasterize_32_WClip;
  174.             srPrivate->rasterFunctions[SRcRasterClip].pointFunction         = 
  175.                 SRPoint_Rasterize_32_WClip;
  176.             srPrivate->rasterFunctions[SRcRasterClip].markerFunction        = 
  177.                 SRMarker_Rasterize_32_WClip;
  178.             srPrivate->rasterFunctions[SRcRasterClip].pixmapMarkerFunction    = 
  179.                 SRPixmapMarker_Rasterize_32_WClip;
  180.  
  181.             break;
  182.         }
  183.         case kQ3XDevicePixelTypeIndexed8: {
  184.             srPrivate->rasterFunctions[SRcRasterBasic].lineFunction         = 
  185.                 SRLine_Rasterize_8;
  186.             srPrivate->rasterFunctions[SRcRasterBasic].pointFunction         = 
  187.                 SRPoint_Rasterize_8;
  188.             srPrivate->rasterFunctions[SRcRasterBasic].markerFunction         = 
  189.                 SRMarker_Rasterize_8;
  190.             srPrivate->rasterFunctions[SRcRasterBasic].pixmapMarkerFunction = 
  191.                 SRPixmapMarker_Rasterize_8;
  192.  
  193.             srPrivate->rasterFunctions[SRcRasterClip].lineFunction             = 
  194.                 SRLine_Rasterize_8_WClip;
  195.             srPrivate->rasterFunctions[SRcRasterClip].pointFunction         = 
  196.                 SRPoint_Rasterize_8_WClip;
  197.             srPrivate->rasterFunctions[SRcRasterClip].markerFunction         = 
  198.                 SRMarker_Rasterize_8_WClip;
  199.             srPrivate->rasterFunctions[SRcRasterClip].pixmapMarkerFunction    = 
  200.                 SRPixmapMarker_Rasterize_8_WClip;
  201.             
  202.             break;
  203.         }
  204.         default: {
  205.             srPrivate->rasterFunctions[SRcRasterBasic].lineFunction         = 
  206.                 SRLine_Rasterize_Null;
  207.             srPrivate->rasterFunctions[SRcRasterBasic].pointFunction         = 
  208.                 SRPoint_Rasterize_Null;
  209.             srPrivate->rasterFunctions[SRcRasterClip].markerFunction         = 
  210.                 SRMarker_Rasterize_Null;
  211.             srPrivate->rasterFunctions[SRcRasterBasic].pixmapMarkerFunction = 
  212.                 SRPixmapMarker_Rasterize_Null;
  213.  
  214.             srPrivate->rasterFunctions[SRcRasterClip].lineFunction             = 
  215.                 SRLine_Rasterize_Null;
  216.             srPrivate->rasterFunctions[SRcRasterClip].pointFunction         = 
  217.                 SRPoint_Rasterize_Null;
  218.             srPrivate->rasterFunctions[SRcRasterClip].markerFunction         = 
  219.                 SRMarker_Rasterize_Null;
  220.             srPrivate->rasterFunctions[SRcRasterClip].pixmapMarkerFunction     = 
  221.                 SRPixmapMarker_Rasterize_Null;
  222.  
  223.             fprintf(stderr, "unsupported pixel depth/type\n");
  224.             
  225.             break;
  226.         }
  227.     }
  228.     
  229.     /*
  230.      *  Check if we're clipped or not, and set up the current raster function
  231.      *  vector to the appropriate function vector.
  232.      */
  233.     if (Q3XDrawRegion_GetClipFlags(
  234.             srPrivate->drawRegion, 
  235.             &clipMaskState) == kQ3Failure) {
  236.         return (kQ3Failure);
  237.     }
  238.         
  239.     if (clipMaskState == kQ3XClipMaskFullyExposed) {
  240.         srPrivate->currentRasterFunctions = 
  241.             &(srPrivate->rasterFunctions[SRcRasterBasic]);
  242.     } else {
  243.         srPrivate->currentRasterFunctions = 
  244.             &(srPrivate->rasterFunctions[SRcRasterClip]);
  245.     }
  246.     
  247.     return (kQ3Success);
  248. }
  249.  
  250.  
  251. /*===========================================================================*\
  252.  *
  253.  *    Routine:    SR_New()
  254.  *
  255.  *    Comments:    Initialize the private state.
  256.  *
  257. \*===========================================================================*/
  258.  
  259. static TQ3Status SR_New(
  260.     TQ3RendererObject         renderer,
  261.     TSRPrivate                *srPrivate,
  262.     void                    *initData)
  263. {
  264.     UNUSED(renderer);
  265.     UNUSED(initData);
  266.     
  267.     assert(renderer != NULL);
  268.     assert(srPrivate != NULL);
  269.  
  270.     /*
  271.      *  Zero everything out.
  272.      */
  273.     memset(srPrivate, 0, sizeof(*srPrivate));
  274.         
  275.     /*
  276.      *  Set the rasterizers to the "null" rasterization functions.
  277.      */
  278.     srPrivate->rasterFunctions[SRcRasterBasic].lineFunction         = 
  279.         SRLine_Rasterize_Null;
  280.     srPrivate->rasterFunctions[SRcRasterBasic].pointFunction         = 
  281.         SRPoint_Rasterize_Null;
  282.     srPrivate->rasterFunctions[SRcRasterBasic].markerFunction         = 
  283.         SRMarker_Rasterize_Null;
  284.     srPrivate->rasterFunctions[SRcRasterBasic].pixmapMarkerFunction = 
  285.         SRPixmapMarker_Rasterize_Null;
  286.  
  287.     srPrivate->rasterFunctions[SRcRasterClip].lineFunction             = 
  288.         SRLine_Rasterize_Null;
  289.     srPrivate->rasterFunctions[SRcRasterClip].pointFunction         = 
  290.         SRPoint_Rasterize_Null;
  291.     srPrivate->rasterFunctions[SRcRasterClip].markerFunction         = 
  292.         SRMarker_Rasterize_Null;
  293.     srPrivate->rasterFunctions[SRcRasterClip].pixmapMarkerFunction     = 
  294.         SRPixmapMarker_Rasterize_Null;
  295.         
  296.  
  297.     return (kQ3Success);
  298. }
  299.  
  300.  
  301. /*===========================================================================*\
  302.  *
  303.  *    Routine:    SR_Delete()
  304.  *
  305.  *    Comments:    Get rid of anything we have a reference to.
  306.  *
  307. \*===========================================================================*/
  308.  
  309. static void SR_Delete(
  310.     TQ3RendererObject    renderer,
  311.     TSRPrivate            *srPrivate)
  312. {
  313.     UNUSED(renderer);
  314.     
  315.     assert(renderer != NULL);
  316.     assert(srPrivate != NULL);
  317.     
  318.     if (srPrivate->viewHighlightAttributeSet != NULL) {
  319.         Q3Object_Dispose(srPrivate->viewHighlightAttributeSet);
  320.         srPrivate->viewHighlightAttributeSet = NULL;
  321.     }
  322.     
  323.     if (srPrivate->camera != NULL) {
  324.         Q3Object_Dispose(srPrivate->camera);
  325.         srPrivate->camera = NULL;
  326.     }
  327. }
  328.  
  329.  
  330. /*===========================================================================*\
  331.  *
  332.  *    Routine:    SR_StartFrame()
  333.  *
  334.  *    Comments:    Called by the View at the start of the frame, set up
  335.  *                the initial data.
  336.  *
  337. \*===========================================================================*/
  338.  
  339. static TQ3Status SR_StartFrame(
  340.     TQ3ViewObject            view,
  341.     TSRPrivate                 *srPrivate,
  342.     TQ3DrawContextObject    drawContext)
  343. {
  344.     TQ3CameraObject        camera;
  345.     TQ3XDrawRegion        drawRegion;
  346.     TQ3Boolean            isActive;
  347.     
  348.     UNUSED(view);
  349.     
  350.     assert(view != NULL);
  351.     assert(srPrivate != NULL);
  352.     assert(drawContext != NULL);
  353.         
  354.     if (Q3View_GetCamera(view, &camera) == kQ3Failure) {
  355.         return (kQ3Failure);
  356.     }
  357.     assert(camera != NULL);
  358.     
  359.     /*
  360.      *  Set primitive counter to zero
  361.      */
  362.     srPrivate->primitiveCount = 0;
  363.     
  364.     /*
  365.      *  Initial camera and transform setup
  366.      */
  367.     SR_SetupPipelineInitCamera(srPrivate, camera);
  368.     Q3Object_Dispose(camera);
  369.     
  370.     /*
  371.      *  Get the current draw context
  372.      */
  373.     srPrivate->currentDrawContext = Q3Shared_GetReference(drawContext);
  374.  
  375.     /*
  376.      *  Clear update flags
  377.      */
  378.     Q3XDrawContext_ClearValidationFlags(srPrivate->currentDrawContext);
  379.  
  380.     /*
  381.      *  Get the first draw region
  382.      */
  383.     Q3XDrawContext_GetDrawRegion(
  384.         srPrivate->currentDrawContext,
  385.         &drawRegion);
  386.     
  387.     Q3XDrawRegion_IsActive(drawRegion, &isActive);
  388.     if (isActive != kQ3True) {
  389.         /* 
  390.          *  Need to find the first active region if there is one 
  391.          */
  392.         while (drawRegion != NULL) {
  393.             Q3XDrawRegion_GetNextRegion(drawRegion, &drawRegion);
  394.             if (drawRegion != NULL) {
  395.                 Q3XDrawRegion_IsActive(drawRegion, &isActive);
  396.                 if (isActive) {
  397.                     break;
  398.                 }
  399.             }
  400.         
  401.         }
  402.     }
  403.     
  404.     if (drawRegion != NULL) {
  405.         Q3XDrawRegion_IsActive(drawRegion, &isActive);
  406.         if (isActive) {
  407.             srPrivate->drawRegion = drawRegion;
  408.         } else {
  409.             srPrivate->drawRegion = NULL;
  410.         }
  411.     } else {
  412.          srPrivate->drawRegion = NULL;
  413.     }
  414.     
  415.     srPrivate->descriptor     = NULL;
  416.     srPrivate->image        = NULL;
  417.                 
  418.     return (kQ3Success);
  419. }
  420.  
  421.  
  422. /*===========================================================================*\
  423.  *
  424.  *    Routine:    SR_Pass()
  425.  *
  426.  *    Comments:    Called at the start of each pass.
  427.  *
  428. \*===========================================================================*/
  429.  
  430. static TQ3Status SR_Pass(
  431.     TQ3ViewObject            view,
  432.     TSRPrivate                 *srPrivate,
  433.     TQ3CameraObject            camera,
  434.     TQ3GroupObject            lightGroup)
  435. {
  436.     TQ3Boolean    isActive;
  437.     
  438.     UNUSED(view);
  439.     UNUSED(lightGroup);
  440.     UNUSED(camera);
  441.     
  442.     assert(srPrivate != NULL);
  443.     
  444.     if (srPrivate->drawRegion == NULL) {
  445.         /*
  446.          *  No active region
  447.          */
  448.         return (kQ3Success);
  449.     }
  450.     
  451.     /*
  452.      *  Call the "startRegion" function, if there is one.
  453.      */
  454.     Q3XDrawRegion_IsActive(srPrivate->drawRegion, &isActive);
  455.     
  456.     if (isActive) {
  457.         TQ3XClipMaskState clipMaskState;
  458.         
  459.         /*
  460.          *  Get the descriptor, and tell the draw region you're starting up
  461.          */
  462.         if (Q3XDrawRegion_StartAccessToImageBuffer(
  463.                 srPrivate->drawRegion,
  464.                 kQ3XDrawRegionServicesClearFlag, 
  465.                 &srPrivate->descriptor, 
  466.                 &srPrivate->image) == kQ3Failure) {
  467.             goto errorCondition;
  468.         }
  469.         
  470.         /*
  471.          *  Find out if you're exposed or not. If not exposed, no need to go 
  472.          *    any further.
  473.          */
  474.         Q3XDrawRegion_GetClipFlags(
  475.             srPrivate->drawRegion, 
  476.             &clipMaskState);
  477.         if (clipMaskState == kQ3XClipMaskNotExposed) {
  478.             return (kQ3Success);
  479.         }
  480.         
  481.         /*
  482.          *  Make sure we've got a raster to draw to
  483.          */
  484.         assert(srPrivate->image);
  485.         if (srPrivate->image == NULL) {
  486.             goto errorCondition;
  487.         }
  488.  
  489.         /*
  490.          *  Set up the frustum-to-device transformation
  491.          */
  492.         SR_SetupRegionDependentTransformations(srPrivate);
  493.         if (SR_UpdateRasterFunctions(srPrivate) == kQ3Failure) {
  494.             goto errorCondition;
  495.         }
  496.     }
  497.  
  498.     return (kQ3Success);
  499.  
  500. errorCondition:
  501.     /*
  502.      *  On error, set rasterizer vector entries to NULL functions.
  503.      */
  504.     srPrivate->rasterFunctions[SRcRasterBasic].lineFunction         = 
  505.         SRLine_Rasterize_Null;
  506.     srPrivate->rasterFunctions[SRcRasterBasic].pointFunction         = 
  507.         SRPoint_Rasterize_Null;
  508.     srPrivate->rasterFunctions[SRcRasterBasic].markerFunction         = 
  509.         SRMarker_Rasterize_Null;
  510.     srPrivate->rasterFunctions[SRcRasterBasic].pixmapMarkerFunction = 
  511.         SRPixmapMarker_Rasterize_Null;
  512.  
  513.     srPrivate->rasterFunctions[SRcRasterClip].lineFunction             = 
  514.         SRLine_Rasterize_Null;
  515.     srPrivate->rasterFunctions[SRcRasterClip].pointFunction         = 
  516.         SRPoint_Rasterize_Null;
  517.     srPrivate->rasterFunctions[SRcRasterClip].markerFunction         =     
  518.         SRMarker_Rasterize_Null;
  519.     srPrivate->rasterFunctions[SRcRasterClip].pixmapMarkerFunction     = 
  520.         SRPixmapMarker_Rasterize_Null;
  521.     
  522.     return (kQ3Failure);
  523. }
  524.  
  525.  
  526. /*===========================================================================*\
  527.  *
  528.  *    Routine:    SR_EndPass()
  529.  *
  530.  *    Comments:    Called by the view at the end of each pass. Multiple passes
  531.  *                will be used if we have multiple draw regions (i.e., there is
  532.  *                more than one monitor)
  533.  *
  534. \*===========================================================================*/
  535.  
  536. static TQ3ViewStatus SR_EndPass(
  537.     TQ3ViewObject     view,
  538.     TSRPrivate         *srPrivate)
  539. {
  540.     TQ3XDrawRegion        currentRegion;
  541.     TQ3Boolean            isActive;
  542.     
  543.     UNUSED(view);
  544.     
  545.     assert(srPrivate != NULL);
  546.  
  547.     if (srPrivate->drawRegion) {
  548.         /*
  549.          *  We are done with this region, call the "endRegion" function, 
  550.          *    if there is one.
  551.          */
  552.         if (Q3XDrawRegion_IsActive(
  553.                 srPrivate->drawRegion, 
  554.                 &isActive) == kQ3Failure) {
  555.             return (kQ3ViewStatusError);
  556.         }
  557.         if (isActive) {
  558.             if (Q3XDrawRegion_End(
  559.                     srPrivate->drawRegion) == kQ3Failure) {
  560.                 return (kQ3ViewStatusError);
  561.             }
  562.         }
  563.     
  564.         /* 
  565.          *  If there is more than one device, request another pass 
  566.          *  for the next device 
  567.          */
  568.         if (Q3XDrawRegion_GetNextRegion(
  569.                 srPrivate->drawRegion, 
  570.                 ¤tRegion) == kQ3Failure) {
  571.             return (kQ3ViewStatusError);
  572.         }
  573.                  
  574.         while (currentRegion != NULL) {
  575.             if (Q3XDrawRegion_IsActive(
  576.                     currentRegion, 
  577.                     &isActive) == kQ3Failure) {
  578.                 return (kQ3ViewStatusError);
  579.             }
  580.             if (isActive) {
  581.                 srPrivate->drawRegion = currentRegion;
  582.                 return (kQ3ViewStatusRetraverse);
  583.             }
  584.             
  585.             if (Q3XDrawRegion_GetNextRegion(
  586.                     currentRegion, 
  587.                     ¤tRegion) == kQ3Failure) {
  588.                 return (kQ3ViewStatusError);
  589.             }
  590.         } 
  591.     }        
  592.     SR_SetupPipelineExit(srPrivate);
  593.  
  594.     /*
  595.      *  We are done with the draw context
  596.      */
  597.     Q3Object_Dispose(srPrivate->currentDrawContext);
  598.     srPrivate->currentDrawContext = NULL;
  599.     
  600.     return (kQ3ViewStatusDone);
  601. }
  602.  
  603.  
  604. /*===========================================================================*\
  605.  *
  606.  *    Routine:    SR_Cancel()
  607.  *
  608.  *    Comments:    Called when the view is cancelled. Dispose of the reference
  609.  *                to the draw context.
  610.  *
  611. \*===========================================================================*/
  612.  
  613. static void SR_Cancel(
  614.     TQ3ViewObject     view,
  615.     TSRPrivate        *srPrivate)
  616. {
  617.     UNUSED(view);
  618.     
  619.     assert(srPrivate != NULL);
  620.  
  621.     SR_SetupPipelineExit(srPrivate);
  622.  
  623.     /*
  624.      *  We are done with the draw context
  625.      */
  626.     if (srPrivate->currentDrawContext) {
  627.         Q3Object_Dispose(srPrivate->currentDrawContext);
  628.         srPrivate->currentDrawContext = NULL;
  629.     }
  630. }
  631.  
  632.  
  633. /*===========================================================================*\
  634.  *
  635.  *    Routine:    SR_Geometry_MetaHandler()
  636.  *
  637.  *    Comments:    Provide entry points for geometric primitive rendering
  638.  *                functions.
  639.  *
  640. \*===========================================================================*/
  641.  
  642. static TQ3XFunctionPointer SR_Geometry_MetaHandler(
  643.     TQ3XMethodType            methodType)
  644. {
  645.     switch (methodType) {
  646.         case kQ3GeometryTypeLine: {
  647.             return (TQ3XFunctionPointer) SR_Geometry_Line;
  648.             break;
  649.         }
  650.         case kQ3GeometryTypeMarker: {
  651.             return (TQ3XFunctionPointer) SR_Geometry_Marker;
  652.             break;
  653.         }
  654.         case kQ3GeometryTypePixmapMarker: {
  655.             return (TQ3XFunctionPointer) SR_Geometry_PixmapMarker;
  656.             break;
  657.         }
  658.         case kQ3GeometryTypePoint: {
  659.             return (TQ3XFunctionPointer) SR_Geometry_Point;
  660.             break;
  661.         }
  662.         case kQ3GeometryTypeTriangle: {
  663.             return (TQ3XFunctionPointer) SR_Geometry_Triangle;
  664.             break;
  665.         }
  666.         default: {
  667.             return NULL;
  668.             break;
  669.         }
  670.     }
  671. }
  672.  
  673.  
  674. /*===========================================================================*\
  675.  *
  676.  *    Routine:    SR_Attribute_MetaHandler()
  677.  *
  678.  *    Comments:    Provide callbacks for updating attributes the sample
  679.  *                renderer cares about. Since it's only a simple wireframe
  680.  *                renderer, we only deal with diffuse color and highlight state.
  681.  *
  682. \*===========================================================================*/
  683.  
  684. static TQ3XFunctionPointer SR_Attribute_MetaHandler(
  685.     TQ3XMethodType            methodType)
  686. {
  687.     switch (methodType) {
  688.         case kQ3AttributeTypeDiffuseColor: {
  689.             return (TQ3XFunctionPointer) SR_Update_DiffuseColor;
  690.             break;
  691.         }
  692.         case kQ3AttributeTypeHighlightState: {
  693.             return (TQ3XFunctionPointer) SR_Update_HighlightState;
  694.             break;
  695.         }
  696.         default: {
  697.             return NULL;
  698.             break;
  699.         }
  700.     }
  701. }
  702.  
  703.  
  704. /*===========================================================================*\
  705.  *
  706.  *    Routine:    SR_Matrix_MetaHandler()
  707.  *
  708.  *    Comments:    Provide callbacks for updating the various transformation
  709.  *                states.
  710.  *
  711. \*===========================================================================*/
  712.  
  713. static TQ3XFunctionPointer SR_Matrix_MetaHandler(
  714.     TQ3XMethodType            methodType)
  715. {
  716.     switch (methodType) {
  717.         case kQ3XMethodTypeRendererUpdateMatrixLocalToWorld: {
  718.             return ((TQ3XFunctionPointer) SR_Update_LocalToWorldMatrix);
  719.             break;
  720.         }
  721.         case kQ3XMethodTypeRendererUpdateMatrixWorldToFrustum: {
  722.             return ((TQ3XFunctionPointer) SR_Update_WorldToFrustumMatrix);
  723.             break;
  724.         }
  725.         case kQ3XMethodTypeRendererUpdateMatrixLocalToFrustum: {
  726.             return ((TQ3XFunctionPointer) SR_Update_LocalToFrustumMatrix);
  727.             break;
  728.         }
  729.         default: {
  730.             return (NULL);
  731.             break;
  732.         }
  733.     }
  734. }
  735.  
  736.  
  737. /*===========================================================================*\
  738.  *
  739.  *    Routine:    SR_Style_MetaHandler()
  740.  *
  741.  *    Comments:    Provide callbacks for updating the styles.
  742.  *                Only backfacing, hightlight, orientation, and fill style
  743.  *                are dealt with in this sample renderer.
  744.  *
  745. \*===========================================================================*/
  746.  
  747. static TQ3XFunctionPointer SR_Style_MetaHandler(
  748.     TQ3XMethodType            methodType)
  749. {
  750.     switch (methodType) {
  751.         case kQ3StyleTypeBackfacing: {
  752.             return (TQ3XFunctionPointer) SR_Update_BackfacingStyle;
  753.             break;
  754.         }
  755.         case kQ3StyleTypeHighlight: {
  756.             return (TQ3XFunctionPointer) SR_Update_HighlightStyle;
  757.             break;
  758.         }
  759.         case kQ3StyleTypeOrientation: {
  760.             return (TQ3XFunctionPointer) SR_Update_OrientationStyle;
  761.             break;
  762.         }
  763.         case kQ3StyleTypeFill: {
  764.             return (TQ3XFunctionPointer) SR_Update_FillStyle;
  765.             break;
  766.         }
  767.         default: {
  768.             return NULL;
  769.             break;
  770.         }
  771.     }
  772. }
  773.  
  774.  
  775. /*===========================================================================*\
  776.  *
  777.  *    Routine:    SR_MetaHandler()
  778.  *
  779.  *    Comments:    Main metahandler. Provides entry point for various
  780.  *                required and optional renderer functions, and for the
  781.  *                metahandlers for geometric primitive rendering and
  782.  *                style, matrix, and attribute updates.
  783.  *
  784. \*===========================================================================*/
  785.  
  786. static TQ3XFunctionPointer SR_MetaHandler(
  787.     TQ3XMethodType        methodType)
  788. {
  789.     switch (methodType) {
  790.         /* 
  791.          *  Object 
  792.          */
  793.         case kQ3XMethodTypeObjectNew: {
  794.             return (TQ3XFunctionPointer) SR_New;
  795.             break;
  796.         }
  797.         case kQ3XMethodTypeObjectDelete: {
  798.             return (TQ3XFunctionPointer) SR_Delete;
  799.             break;
  800.         }
  801.             
  802.         /* 
  803.          *  I/O 
  804.          */
  805.         case kQ3XMethodTypeObjectRead: {
  806.             return (TQ3XFunctionPointer) SR_Read;
  807.             break;
  808.         }
  809.         case kQ3XMethodTypeObjectAttach: {
  810.             return (TQ3XFunctionPointer) NULL;
  811.             break;
  812.         }
  813.         case kQ3XMethodTypeObjectTraverse: {
  814.             return (TQ3XFunctionPointer) SR_Traverse;
  815.             break;
  816.         }
  817.         case kQ3XMethodTypeObjectWrite: {
  818.             return (TQ3XFunctionPointer) NULL;
  819.             break;
  820.         }
  821.             
  822.         /* 
  823.          *  Renderer 
  824.          */
  825.         case kQ3XMethodTypeRendererStartFrame: {
  826.             return (TQ3XFunctionPointer) SR_StartFrame;
  827.             break;
  828.         }
  829.         case kQ3XMethodTypeRendererStartPass: {
  830.             return (TQ3XFunctionPointer) SR_Pass;
  831.             break;
  832.         }
  833.         case kQ3XMethodTypeRendererEndPass: {
  834.             return (TQ3XFunctionPointer) SR_EndPass;
  835.             break;
  836.         }
  837.         case kQ3XMethodTypeRendererCancel: {
  838.             return (TQ3XFunctionPointer) SR_Cancel;
  839.             break;
  840.         }
  841.             
  842.         /* 
  843.          *  Renderer Draw 
  844.          */
  845.         case kQ3XMethodTypeRendererSubmitGeometryMetaHandler: {
  846.             return (TQ3XFunctionPointer) SR_Geometry_MetaHandler;
  847.             break;
  848.         }
  849.  
  850.         /* 
  851.          *  Renderer Update 
  852.          */
  853.         case kQ3XMethodTypeRendererUpdateStyleMetaHandler: {
  854.             return (TQ3XFunctionPointer) SR_Style_MetaHandler;
  855.             break;
  856.         }
  857.         case kQ3XMethodTypeRendererUpdateAttributeMetaHandler: {
  858.             return (TQ3XFunctionPointer) SR_Attribute_MetaHandler;
  859.             break;
  860.         }
  861.         case kQ3XMethodTypeRendererUpdateMatrixMetaHandler: {
  862.             return (TQ3XFunctionPointer) SR_Matrix_MetaHandler;
  863.             break;
  864.         }
  865.         
  866.         /*
  867.          *  Modal dialog
  868.          */
  869.         case kQ3XMethodTypeRendererModalConfigure: {
  870. #if defined(WINDOW_SYSTEM_MACINTOSH) && WINDOW_SYSTEM_MACINTOSH
  871.             return (TQ3XFunctionPointer) SR_MacModalDialog;
  872. #elif defined (WINDOW_SYSTEM_WIN32) && WINDOW_SYSTEM_WIN32
  873.             return (TQ3XFunctionPointer) SR_WinModalDialog;
  874. #endif  /*  WINDOW_SYSTEM_MACINTOSH  */
  875.             break;
  876.         }
  877.         
  878.         /*
  879.          *  "isInteractive" control
  880.          */
  881.         case kQ3XMethodTypeRendererIsInteractive: {
  882.             return (TQ3XFunctionPointer) kQ3True;
  883.             break;
  884.         }
  885.         
  886.         /*
  887.          *  renderer name string
  888.          */
  889.         case kQ3XMethodTypeRendererGetNickNameString: {
  890.             return (TQ3XFunctionPointer) SR_GetNameString;
  891.             break;
  892.         }
  893.         
  894.         /*
  895.          *  Configuration data
  896.          */
  897.         case kQ3XMethodTypeRendererGetConfigurationData: {
  898.             return (TQ3XFunctionPointer) SR_GetConfigurationData;
  899.             break;
  900.         }
  901.  
  902.         case kQ3XMethodTypeRendererSetConfigurationData: {
  903.             return (TQ3XFunctionPointer) SR_SetConfigurationData;
  904.             break;
  905.         }
  906.  
  907.         default: {
  908.             return NULL;
  909.             break;
  910.         }
  911.     }
  912. }
  913.  
  914.  
  915. /*===========================================================================*\
  916.  *
  917.  *    Routine:    SR_Read()
  918.  *
  919.  *    Comments:    
  920.  *
  921. \*===========================================================================*/
  922.  
  923. static TQ3RendererObject SR_Read(
  924.     TQ3FileObject        file)
  925. {
  926.     UNUSED(file);
  927.     
  928.     return Q3Renderer_NewFromType(SRgClassType);
  929. }
  930.  
  931.  
  932. /*===========================================================================*\
  933.  *
  934.  *    Routine:    SR_Traverse()
  935.  *
  936.  *    Comments:    
  937.  *
  938. \*===========================================================================*/
  939.  
  940. static TQ3Status SR_Traverse(
  941.     TQ3RendererObject    renderer,
  942.     void                *unused,
  943.     TQ3ViewObject        view)
  944. {
  945.     UNUSED(unused);
  946.     UNUSED(renderer);
  947.     
  948.     return Q3XView_SubmitWriteData(view, 0, NULL, NULL);
  949. }
  950.  
  951.  
  952. /*===========================================================================*\
  953.  *
  954.  *    Routine:    SR_Register()
  955.  *
  956.  *    Comments:    Create/register this sample renderer, as a subclass of 
  957.  *                kQ3SharedTypeRenderer
  958.  *
  959. \*===========================================================================*/
  960.  
  961. static TQ3Status SR_Register(
  962.     void)
  963. {
  964.     /*
  965.      *  Create/register the class
  966.      */
  967.     SRgRendererClass = 
  968.         Q3XObjectHierarchy_RegisterClass(
  969.             kQ3SharedTypeRenderer,
  970.             &SRgClassType,
  971.             "SampleRenderer",
  972.             SR_MetaHandler,
  973.             NULL,
  974.             0,
  975.             sizeof(TSRPrivate));
  976.  
  977.     /*
  978.      *  Make sure it worked
  979.      */
  980.     if (SRgRendererClass == NULL) {
  981.         return (kQ3Failure);
  982.     }
  983.  
  984.     return (kQ3Success);
  985. }
  986.  
  987. #if defined(WINDOW_SYSTEM_MACINTOSH) && WINDOW_SYSTEM_MACINTOSH
  988.  
  989. /*===========================================================================*\
  990.  *
  991.  *    Routine:    SR_Initialize()
  992.  *
  993.  *    Comments:    This is the initialization routine called by the shared library
  994.  *                manager.  This function passes SR_Register to QuickDraw 3D
  995.  *
  996. \*===========================================================================*/
  997.  
  998. OSErr SR_Initialize( 
  999.     const CFragInitBlock    *initBlock)
  1000. {
  1001.     TQ3XSharedLibraryInfo    sharedLibraryInfo;
  1002.     OSErr                    err = noErr;
  1003.     
  1004.     sharedLibraryInfo.registerFunction     = SR_Register;
  1005.     sharedLibraryInfo.sharedLibrary     = (unsigned long)
  1006.                                                 initBlock->connectionID;
  1007.                                                 
  1008.     Q3XSharedLibrary_Register(&sharedLibraryInfo);
  1009.     
  1010.     SRgSharedLibrary = (unsigned long)initBlock->connectionID;
  1011.     
  1012.     err = SR_CreateAliasHandle(initBlock);
  1013.     
  1014.     return (err);
  1015. }
  1016.  
  1017. #endif
  1018.  
  1019. #if defined(WINDOW_SYSTEM_WIN32) && WINDOW_SYSTEM_WIN32
  1020.  
  1021. HINSTANCE    hinstMyDLL = NULL;
  1022.  
  1023. /*===========================================================================*\
  1024.  *
  1025.  *    Routine:    DllMain()
  1026.  *
  1027.  *    Comments:    The Win32 extension entry point
  1028.  *
  1029. \*===========================================================================*/
  1030.  
  1031. BOOL WINAPI DllMain(
  1032.     HINSTANCE    hinstDLL,
  1033.     DWORD        fdwReason,
  1034.     LPVOID        lpvReserved)
  1035. {
  1036.     TQ3XSharedLibraryInfo    sharedLibraryInfo;
  1037.     
  1038.     if (fdwReason == DLL_PROCESS_ATTACH) {
  1039.         hinstMyDLL = hinstDLL;
  1040.  
  1041.         sharedLibraryInfo.registerFunction = SR_Register;
  1042.         sharedLibraryInfo.sharedLibrary = (unsigned long)hinstDLL;
  1043.         if (Q3XSharedLibrary_Register(&sharedLibraryInfo) == kQ3Success) {
  1044.             return TRUE;
  1045.         } else {
  1046.             return FALSE;
  1047.         }
  1048.     }
  1049.     
  1050.     if (fdwReason == DLL_PROCESS_DETACH) {
  1051.         Q3XSharedLibrary_Unregister((unsigned long)hinstDLL);
  1052.     }
  1053.  
  1054.     return (TRUE);
  1055. }
  1056.  
  1057. #endif /* WINDOW_SYSTEM_WIN32 */
  1058.  
  1059.  
  1060. /*===========================================================================*\
  1061.  *
  1062.  *    Routine:    SR_Exit()
  1063.  *
  1064.  *    Comments:    Called on exiting from QD3D, this function unregisters this
  1065.  *                plug-in renderer.
  1066.  *
  1067. \*===========================================================================*/
  1068.  
  1069. TQ3Status SR_Exit( 
  1070.     void)
  1071. {
  1072.     if (SRgSharedLibrary != NULL) {
  1073.         Q3XSharedLibrary_Unregister(SRgSharedLibrary);
  1074.         SRgSharedLibrary = NULL;
  1075.     }
  1076.     
  1077. #if defined(WINDOW_SYSTEM_MACINTOSH) && WINDOW_SYSTEM_MACINTOSH
  1078.     SR_FreeAliasHandle();
  1079. #endif  /*  WINDOW_SYSTEM_MACINTOSH  */
  1080.     
  1081.     return (kQ3Success);
  1082. }
  1083.  
  1084.  
  1085. #if defined(WINDOW_SYSTEM_MACINTOSH) && WINDOW_SYSTEM_MACINTOSH
  1086.  
  1087. /*===========================================================================*\
  1088.  *
  1089.  *    Routine:    SR_CreateAliasHandle()
  1090.  *
  1091.  *    Comments:    
  1092.  *
  1093. \*===========================================================================*/
  1094.  
  1095. static OSErr SR_CreateAliasHandle( 
  1096.     const CFragInitBlock    *initBlock)
  1097. {    
  1098.     OSErr        err = noErr;
  1099.     
  1100.     if (initBlock->fragLocator.where == kDataForkCFragLocator) {        
  1101.         err = NewAlias(
  1102.                     NULL, 
  1103.                     initBlock->fragLocator.u.onDisk.fileSpec, 
  1104.                     &SRgAliasHandle);
  1105.     }
  1106.     
  1107.     return (err);
  1108. }
  1109.  
  1110.  
  1111. /*===========================================================================*\
  1112.  *
  1113.  *    Routine:    SR_FreeAliasHandle()
  1114.  *
  1115.  *    Comments:    
  1116.  *
  1117. \*===========================================================================*/
  1118.  
  1119. static TQ3Status SR_FreeAliasHandle(
  1120.     void)
  1121. {
  1122.     if (SRgAliasHandle != NULL) {
  1123.         DisposeHandle((Handle) SRgAliasHandle);
  1124.     }
  1125.     
  1126.     return (kQ3Success);
  1127. }
  1128.  
  1129. #endif  /*  WINDOW_SYSTEM_MACINTOSH  */
  1130.